Data processors such as microprocessors typically use data register files located in close proximity to the data path functional units to temporarily store data. These data registers are typically so close to the data path functional units that they can be both read and written to in a single data processing instruction cycle. It typically requires more time and often much more instructions to access variables stored only in memory.
Data processors are generally programmed in a high level language that is easily understandable to a programmer. High level languages typically do not expose the data registers to direct manipulation by the programmer. These high level languages typically consider the programmer generated source code and allocate registers during conversion to object code directly executable by the data processor. This conversion is called compiling. During compilation the compiler must determine how to use the available data registers to perform the functions specified by the programmer in the source code. This process is called register allocation.
Some data processors permit multiple versions of certain instructions. These data processors are said to have a tiered architecture. Some versions of these instructions are more efficient in program memory use. But such program memory efficiency may come at the cost of sacrificing the ability to reach some of the available data registers. Efficiently allocating registers on such tiered architectures is a difficult problem. The compiler must attempt to generate the most efficient object code to minimize program memory size while preserving operational speed.
There are two solutions known for register allocation in a tiered architecture. The first solution allocates registers to the inputs/outputs of multi-version instructions from the whole register file without forcing them to be from the more restricted subset of registers. Thus all multi-version instructions are implemented in the least restrictive data register form. This will often result in some of the multi-version instructions not resolving to their most efficient form because their inputs are not part of the restricted registers subset. The second solution always restricts the inputs and outputs of the instructions to belong to the most restricted register set. This insures that any instructions within the most restricted register set will properly resolve to the efficient form. This often results in registers being unavailable which might have been available in a less restrictive register set instruction, perhaps even the instruction that would have been selected by the compiler absent the extreme register restriction. When registers are unavailable for some these instructions, the data must be loaded from memory. The additional memory requests required makes the eventual generated code far less optimal since spilling to memory is inefficient in terms of both program memory and execution time.
From this description, it should be understood that neither prior art technique insures optimal object code.